#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct AndroidBitmap{
	int a;
	int b;
} AndroidBitmap_;	// 前面带有typedef，则AndroidBitmap_，是一个结构体别名，别名可以有多个，结构体别名的意义是 struct AndroidBitmap = AndroidBitmap

struct Bitmap{
	int a;
	int b;
} bp,bp_;			// 不带typedef，bp，和bp_，表示一个变量

void getAndroidBitmap(AndroidBitmap_ *bitmapInfo){
	bitmapInfo->a = 200;
	bitmapInfo->b = 300;
}

int main()
{
	// 内存四驱模型
	// 程序运行步骤：
	// 1.程序从硬盘加载到内存中
	// 2.加载到内存后，会将c代码分为4个区
	// 3.系统找到main函数入口，然后去执行代码
	
	// 四区模型：
	// 1.栈区			 ：	编译器自动分配的，存放一下局部变量和函数，这部分内存会是自动回收的
	// 2.堆区			 ：	一般情况会是我们自己申请的内存，并且需要自己进行释放
	// 3.全局区（静态区）： 静态常量，字符串
	// 4.程序代码区：	 ：	存放函数体二进制代码

	AndroidBitmap_ *bitmapInfo = (AndroidBitmap_*)malloc(sizeof(AndroidBitmap_));

	// 传递一个结构体指针
	getAndroidBitmap(bitmapInfo);

	printf("a=%d, b=%d \n",bitmapInfo->a,bitmapInfo->b);

	// 释放bitmapInfo，但是不能对它进行多次释放
	if(bitmapInfo != NULL)
	{
		free(bitmapInfo);
		bitmapInfo = NULL; // 需要置空
	}

	char* p1 = NULL;	// p1 = NULL 此时p1指向的是0x00000000的地方，这是编译器持有的，无法对该地址进行操作
	//strcpy(p1,"123456");
	
	char buff1[100] = {0};
	char buff2[50];
	printf("%d , %d \n",buff1[1],buff1[88]);
	printf("%d , %d \n",buff2[1],buff2[88]);

	// 栈区
	char ch1[] = "123456"; // len=6, 字符串都会以('/0')进行结尾,所以内存占用上是 size=7
	printf("ch1, len = %ld, size = %ld\n",strlen(ch1),sizeof(ch1));

	// 常量区
	char *ch2 = "987654";  
	// strlen(ch2)： 计算的是纯字符串的长度
	// sizeof(ch2)： 计算的是ch2指针所占用内存的大小
	// sizeof(*ch2)：计算的是指针对应第0个位置占用空间的大小
	printf("ch2, len = %ld, sizeof(ch2) = %ld, sizeof(*ch2) = %ld\n",strlen(ch2),sizeof(ch2),sizeof(*ch2));
	// 获取ch2指针首地址对应的值
	printf("ch2 = %c\n",*ch2);

	// 堆区
	char *ch3 = (char *)malloc(sizeof(char)*6);
	printf("ch3, len = %ld, sizeof(ch3) = %ld, sizeof(*ch3) = %ld\n",strlen(ch3),sizeof(ch3),sizeof(*ch3));

	/*
	 * 函数设置原则：
	 * 1.确定参数，专递指针
	 * 2.函数健壮性，参数检查，NULL，类型错误
	 * 3.异常检测，抛出说明
	 * 4.不要轻易的去改变指针，大部分指针参数会用const进行修饰
	 * */

	exit(0);
}





